﻿using System.Web;
using Wisdom.Core;

namespace Wisdom.Web.Mvc
{
    /// <summary>
    ///   Extension methods for the HttpResponseBase class
    /// </summary>
    public static class HttpResponseBaseExtensions
    {
        /// <summary>
        ///   Reloads the current page / handler by performing a redirect to the current baseUrl
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        public static void Reload(this HttpResponseBase response)
        {
            response.Redirect(HttpContext.Current.Request.Url.ToString(), true);
        }

        /// <summary>
        ///   Performs a response redirect and allows the baseUrl to be populated with string format parameters.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        /// <param name = "urlFormat">The URL including string.Format placeholders.</param>
        /// <param name = "values">The values to the populated.</param>
        public static void Redirect(this HttpResponseBase response, string urlFormat, params object[] values)
        {
            response.Redirect(urlFormat, true, values);
        }

        /// <summary>
        ///   Performs a response redirect and allows the baseUrl to be populated with string format parameters.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        /// <param name = "urlFormat">The URL including string.Format placeholders.</param>
        /// <param name = "endResponse">If set to <c>true</c> the response will be terminated.</param>
        /// <param name = "values">The values to the populated.</param>
        public static void Redirect(this HttpResponseBase response, string urlFormat, bool endResponse,
                                    params object[] values)
        {
            var url = string.Format(urlFormat, values);
            response.Redirect(url, endResponse);
        }

        /// <summary>
        ///   Performs a response redirect and allows the baseUrl to be populated with a query string.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        /// <param name = "baseUrl">The URL.</param>
        /// <param name = "queryString">The query string.</param>
        public static void Redirect(this HttpResponseBase response, string baseUrl, UrlQueryString queryString)
        {
            response.Redirect(baseUrl, queryString, true);
        }

        /// <summary>
        ///   Performs a response redirect and allows the baseUrl to be populated with a query string.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        /// <param name = "baseUrl">The base URL.</param>
        /// <param name = "queryString">The query string.</param>
        /// <param name = "endResponse">If set to <c>true</c> the response will be terminated.</param>
        public static void Redirect(this HttpResponseBase response, string baseUrl, UrlQueryString queryString,
                                    bool endResponse)
        {
            baseUrl = queryString.ToString(baseUrl);
            response.Redirect(baseUrl, endResponse);
        }

        /// <summary>
        ///   Returns a 404 to the client and ends the response.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        public static void SetFileNotFound(this HttpResponseBase response)
        {
            response.SetFileNotFound(true);
        }

        /// <summary>
        ///   Returns a 404 to the client and optionally ends the response.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        /// <param name = "endResponse">If set to <c>true</c> the response will be terminated.</param>
        public static void SetFileNotFound(this HttpResponseBase response, bool endResponse)
        {
            response.SetStatus(404, "Not Found", endResponse);
        }

        /// <summary>
        ///   Returns a 500 to the client and ends the response.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        public static void SetInternalServerError(this HttpResponseBase response)
        {
            response.SetInternalServerError(true);
        }

        /// <summary>
        ///   Returns a 500 to the client and optionally ends the response.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        /// <param name = "endResponse">If set to <c>true</c> the response will be terminated.</param>
        public static void SetInternalServerError(this HttpResponseBase response, bool endResponse)
        {
            response.SetStatus(500, "Internal Server Error", endResponse);
        }

        /// <summary>
        ///   Set the specified HTTP status code and description and optionally ends the response.
        /// </summary>
        /// <param name = "response">The HttpResponseBase to perform on.</param>
        /// <param name = "code">The status code.</param>
        /// <param name = "description">The status description.</param>
        /// <param name = "endResponse">If set to <c>true</c> the response will be terminated.</param>
        public static void SetStatus(this HttpResponseBase response, int code, string description, bool endResponse)
        {
            response.StatusCode = code;
            response.StatusDescription = description;

            if (endResponse) response.End();
        }

        /// <summary>
        /// Writes the json.
        /// </summary>
        /// <param name="instance">The instance.</param>
        /// <param name="json">The json.</param>
        public static void WriteJson(this HttpResponseBase instance, string json)
        {
            Guard.IsNotNull(instance, "instance");
            Guard.IsNotNull(json, "json");

            instance.Clear();
            instance.ContentType = "application/json";
            instance.Write(json);
        }
    }
}